/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bitoon.basketdudes.ws;

import com.bitoon.basketdudes.jpa.*;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.*;
import javax.persistence.*;
import javax.servlet.http.*;
import org.apache.commons.codec.binary.Hex;
import org.apache.log4j.*;


/**
 * Clase para dar soporte a los Torneos de usuario
 * Created on : 18-ago-2011, 16:23:39
 * @author pacoFELC
 */
public class Competicion {

    Logger                  log     = Logger.getLogger(Competicion.class);
    Configuracion           conf    = null;
    EntityManagerFactory    emf     = null;
    EntityManager           m_em    = null;

    public Competicion() {
        try {
            // JPA Units
            emf = PersistenceManager.getInstance().getEntityManagerFactory("jpa_basket");
            conf = Configuracion.getInstance();
        } catch (Exception e) {
            log.error("[ERROR][constructor]: No se puedo conectar a la base de datos: " , e);
        }
    }

    /*
    public void setEntityManager ( EntityManager p_basket ) {
        try {
            // JPA Units
            m_em   = p_basket;
        } catch (Exception e) {
            log.error("[ERROR][constructor]: No se puedo conectar a la base de datos: " , e);
        }
    }
     *
     */

    /*
    public EntityManager getEntityManager (  ) {
        try {
            if ( m_em == null) {
                emf = PersistenceManager.getInstance().getEntityManagerFactory("jpa_basket");
                m_em  =  emf.createEntityManager();
            }
        } catch (Exception e) {
            log.error("[ERROR][constructor]: No se puedo conectar a la base de datos: " , e);
        }


        return m_em;
    }
     * 
     */


    public String wsTorneoPendientes( HttpServletRequest request, HttpServletResponse response ) {
        /* Consulta los partidos todavía no celebrados en torneos de usuario por un equipo
	   Respuesta:
	   Estará ordenada internamente al recuperar de la base de datos por calendario.f_fin de menor a mayor
           para que se jueguen primero los partidos que antes finalizará su fecha tope de celebración

	   error | cuantos |{torneo_id | rival | jornada | nombre |}  */

        int             equipo_id   = -1;
        EntityManager   em          = null;
        String          respuesta   = "";

        try {
            em = emf.createEntityManager(); // check 07.08.2012
            equipo_id = Integer.parseInt(request.getParameter("equipo_id"));

            Query q = em.createNamedQuery("Calendario.EquipoPendientes");
            q.setParameter("equipo_id", equipo_id);
            q.setParameter("fecha", new Date() );

            List<Calendario> lista = (List<Calendario>)q.getResultList();

            respuesta = "0|"+lista.size()+"|";

            // Tomamos el primer enfrentamiento y asignamos la jornada al partido
            for ( int i=0;i<lista.size();i++){
                Calendario calendario = lista.get(i);

                respuesta+=calendario.getTemporada().getId()+"|";
                Equipo rival = null;
                if ( calendario.getEquipoId1()==equipo_id ) {
                    respuesta+='0'+"|";
                    rival = calendario.getEquipo2();
                } else {
                    respuesta+='1'+"|";
                    rival = calendario.getEquipo1();
                }
                respuesta   +=rival.getId()+"|"
                            +rival.getNombre()+"|"
                            +rival.getNick()+"|"
                            +rival.getNivel()+"|"
                            +rival.getUsuario().getNick()+"|"
                            +rival.getAspectoEquipo().getLogoimgId()+"|";

                respuesta+=calendario.getNumJornada()+"|";
                respuesta+=calendario.getTemporada().getTorneo().getNombre()+"|";

            }

        } catch (Exception e) {
            try { 
                if (em     != null && em.getTransaction().isActive() )                
                    em.getTransaction().rollback();
            } catch (Exception e2) { }
            log.error("[torneoPendientes]: " , e);
            respuesta="-1|"+e.getMessage();
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
        return respuesta;

    }

    public String wsNuevoPartido( HttpServletRequest request, HttpServletResponse response, int p_tipo_partido ) {
        int equipo1=-1, equipo2=-1;
        int equipo_usuario_id=-1, tipo=-1;
        EntityManager em = null;

        try {
            em = emf.createEntityManager(); // check 07.08.2012

            // Si el tipo de partido es 0 se busca el parametro del request
            if ( p_tipo_partido == 0) {
                tipo    = Integer.parseInt(request.getParameter("tipo"));
            } else {
                tipo    = p_tipo_partido;
            }

            if ( request.getParameter("equipo1")==null || request.getParameter("equipo2")==null ) {
                return "-6|"; // Parametros incorrectos
            }

            equipo1 = Integer.parseInt(request.getParameter("equipo1"));
            equipo2 = Integer.parseInt(request.getParameter("equipo2"));

            if ( equipo1 < 0 ) {
                LoginAction la = new LoginAction();
                HttpSession miSesion    = request.getSession(true);
                String      sesion_id   = miSesion.getId();
                equipo_usuario_id = la.comprobarSesionEquipo(sesion_id,equipo2,em);
                equipo1=Math.abs(equipo1);
            }
            if ( equipo2 < 0 ) {
                LoginAction la = new LoginAction();
                HttpSession miSesion    = request.getSession(true);
                String      sesion_id   = miSesion.getId();
                equipo_usuario_id = la.comprobarSesionEquipo(sesion_id,equipo1,em);
                equipo2=Math.abs(equipo2);
            }

            if (  tipo==4 && equipo_usuario_id < 0 ) {
                log.error(" Sesion incorrecta: " + equipo1+ " rival" + equipo2 +
                          " tipo:" + tipo + " error: " + equipo_usuario_id);
                return "-7|"; // Sesión Equipo incorrecta
            }
        } catch (Exception e) {
            log.error("Error: ", e);
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }

        // Permitimos esta llamada porque la conexión previa ha sido cerrada
        return wsCrearNuevoPartido( request, response, equipo1, equipo2, tipo );
    }

    /* Crea un nuevo partido
     * Errores
        -3 No pueden jugar dos equipos del mismo usuario
        -4 No hay servidores libres en la zona
        -5 Indeterminado
        -6 Enfrentamiento no encontrado     
        -7 Enfrentamiento reciente
    */
    
    public String wsCrearNuevoPartido( HttpServletRequest request, HttpServletResponse response, int equipo1, int equipo2, int p_tipo_partido ) {
        Integer error   = 0;
        String  retorno = "";
        Partida partido = null;

        EntityManager   em      = null;
        LoginAction     la      = null;

        int tiempo=-1, zona=-1;
        String passw;
        Equipo r_equipo1 = null;
        Equipo r_equipo2 = null;                
        try {

            tiempo  = Integer.parseInt(request.getParameter("tiempo"));
            zona    = Integer.parseInt(request.getParameter("zona"));

            /* Actualmente no utilizado */
            passw   = request.getParameter("pass");

            em = emf.createEntityManager(); // check 07.08.2012

            log.debug("[new_match] equipos: " + equipo1 + " | " + equipo2 + " tipo: " + p_tipo_partido + " tiempo: " + tiempo + " zona:" + zona );

            la = new LoginAction();

            if ( equipo1 == equipo2) {
                /* No puede jugarse contra si mismo */
                error   = -2;
            } else {
                r_equipo1 = la.BuscarEquipo ( em, equipo1);
                if ( r_equipo1 == null) {
                    log.error("[NEW_MATCH] No existe el equipo1 " + equipo1);
                }
                r_equipo2 = la.BuscarEquipo ( em, equipo2);
                if ( r_equipo2 == null) {
                    log.error("[NEW_MATCH] No existe el equipo2 " + equipo2);
                }

                if ( EnfrentadosUltimosPartidos(em,r_equipo1,r_equipo2) || 
                     EnfrentadosUltimosPartidos(em,r_equipo2,r_equipo1))
                {
                    log.error("[NEW_MATCH] Enfrentamiento Reciente " + equipo1 + "<->" + equipo2 );
                    error   = -7;                    
                }
                
               log.debug( "[NEW_MATCH] "+ r_equipo1.getId()+" : " +r_equipo2.getId()+ " min"+ tiempo + " tipo "+ p_tipo_partido);

               if ( r_equipo1.getUsuario().getId() == r_equipo2.getUsuario().getId()) {
                   /* No pueden jugar dos equipos del mismo usuario */
                    error   = -3;
               } 
               
               if ( error == 0) {

                    partido = new Partida();
                    partido.setEquipo1(r_equipo1);
                    partido.setEquipo2(r_equipo2);

                    Servicio servicio = la.dameServidorJuego ( em, zona );

                   if ( servicio != null ) {
                        partido.setIp       (servicio.getIp     ());
                        partido.setPuerto   (servicio.getPuerto ());
                        error   = 0;

                        switch ( tiempo ) {
                            case 1:
                                partido.setTiempo(1);
                                break;
                            case 2:
                                partido.setTiempo(2);
                                break;
                            case 3:
                                partido.setTiempo(3);
                                break;
                            default:
                                partido.setTiempo(2);
                                break;
                        }
                        partido.setTipo(p_tipo_partido);
                        if ( p_tipo_partido == 2){
                            // Partido de trofeo de usuario

                            // Buscamos en calendario el partido cuya fecha de fin sea más temprana
                            // y que involucre a ambos contendientes

                            Query q = em.createNamedQuery("Calendario.PartidoTemprano");
                            q.setParameter("equipo_id1", equipo1);
                            q.setParameter("equipo_id2", equipo2);
                            q.setParameter("fecha", new Date() );
/*
                            Query q = em.createNamedQuery("Calendario.findAll");
*/
log.debug("parametros "+equipo1 + " " + equipo2 + " " + new Date());
                            List<Calendario> lista = (List<Calendario>)q.getResultList();

                            if ( lista.size()==0) {
                               error= -6; // Enfrentamiento no encontrado
                               // throw new ExcepcionGeneral( -6, "Enfrentamiento no encontrado" + equipo1 + " " + equipo2 );
                            } else {
                                // Tomamos el primer enfrentamiento del calendario y asignamos su identificador al partido
                                Calendario calendario = lista.get(0);
                                partido.setCompeticionId(calendario.getId());
                                if ( r_equipo1.getId() != calendario.getEquipoId1() || 
                                     r_equipo2.getId() != calendario.getEquipoId2() ) {
                                    partido.setEquipo1(r_equipo2);
                                    partido.setEquipo2(r_equipo1);
                                    partido.setTiempo(2);
                                }

log.debug(" Calendario Jornada  "+calendario.getId());
                            }
                        }

                        if ( error == 0 ) {
                            partido.setfAlta(new Date());
                            partido.setEstado(-1); // Estado -1, la partida no está iniciada

                            em.getTransaction().begin();
                            em.persist(partido);
                            em.getTransaction().commit();
                       }
                   } else {
                        /* No hay servidores libres en la zona */
                        error= -4;
                   }
                }
            }
        } catch (Exception e) {
            log.error("[ERROR][nuevoPartido]: " , e);
            error   = -5;
            retorno = "-1";
            if (em     != null && em.getTransaction().isActive() )     em.getTransaction().rollback();
        } finally {
            try { em.close(); } catch (Exception e) { }; // revisado 09/08/2012
        }

log.debug(" NUEVO PARTIDO Error" + error);

        retorno = error.toString() + "|";
        if ( partido != null && error == 0) {
            retorno += partido.getId().toString() + '|' + partido.getIp() + '|' + 
                       partido.getPuerto() + '|' + partido.getTipo() + '|' + partido.getTiempo() + '|' +
// 04-jun-2012 añadimos los equipos a la respuesta para comprobaciones posteriores
                       partido.getEquipo1Id()+ '|'+partido.getEquipo2Id()+'|';

log.debug(" NUEVO PARTIDO Retorno" + retorno);
        }

        return retorno;
    }


    public void actualizarTorneoUsuario( int p_calendario_id, int p_partido_id, int p_estado, Date p_fecha,
                                         int p_tanteo1, int p_tanteo2, int abandonador,
                                         EntityManager p_em) throws ExcepcionGeneral{

        // Actualiza el resultado de un partido de un torneo de usuario
        // Si el estado pasado como parámetro es:
        //       1 actualiza el enfrentamiento como un partido jugado con normalidad
        //       2 perdido por ambos
        //       3 ganador decidido por el promotor

        log.debug(" actualizarTorneoUsuario calendario:" + p_calendario_id + " partido: " + p_partido_id + " estado: "+ p_estado+ " abandonador: " + abandonador );

        //EntityManager em=null;

        try {

            //em = emf.createEntityManager(); // check 07.08.2012

            // buscamos el calendario
            Query q = p_em.createNamedQuery("Calendario.findById");
            q.setParameter("id", p_calendario_id );
            Calendario cal = (Calendario)q.getSingleResult();
            if ( cal == null) {
                throw new ExcepcionGeneral( -3, "Enfrentamiento no encontrado" + p_calendario_id  );
            }

            // actualizamos f_partido, tanteos y estado
            cal.setFPartido(p_fecha);
            cal.setTanteo1((short)p_tanteo1);
            cal.setTanteo2((short)p_tanteo2);
            cal.setEstado((short)10); // disputado
            cal.setPartidoId(p_partido_id);
            short ganados1=0,ganados2=0,perdidos1=0,perdidos2=0,puntos1=1,puntos2=1;

            switch ( p_estado) {
                case 1:
                case 3:
                    if ( p_tanteo1>p_tanteo2) {
                        puntos1 = 2;
                        if ( abandonador > 0 ) {
                            puntos2 = 0;
                        } else {
                            puntos2 = 1;
                        }
                        ganados1 =1;
                        perdidos2 =1;
                    } else {
                        puntos2 = 2;
                        if ( abandonador > 0 ) {
                            puntos1 = 0;
                        } else {
                            puntos1 = 1;
                        }
                        ganados2 = 1;
                        perdidos1 = 1;
                    }
                    break;
                case 2:
                    perdidos1   =0;
                    perdidos2   =0;
                    puntos1     =0;
                    puntos2     =0;
                    break;
            }

            // buscamos a los dos participles y
            // Actualizamos ganados, perdidos, puntos, y favor/contra
            actualizarParticipe( cal.getEquipoId1(), cal.getTemporada().getId(), puntos1,
                                 ganados1, perdidos1, p_tanteo1, p_tanteo2, p_em );
            actualizarParticipe( cal.getEquipoId2(), cal.getTemporada().getId(), puntos2,
                                 ganados2, perdidos2, p_tanteo2, p_tanteo1, p_em );
        } catch (Exception e) {
            log.error("Error: ", e);
        } 

    }

    private void actualizarParticipe( int   p_equipo,  int   p_temporada, int p_puntos,
                                      short p_ganados, short p_perdidos,  int p_favor, int p_contra,
                                      EntityManager p_em)
                            throws ExcepcionGeneral {

        try {
            //em = emf.createEntityManager(); // check 07.08.2012
            log.debug("Buscando Participe "+ p_equipo + " "+ p_temporada+ " PUNTOS"+p_puntos);
            Query qp = p_em.createNamedQuery("Participe.findByTemporadaEquipo");
            qp.setParameter("equipo_id",     p_equipo);
            qp.setParameter("temporada_id",  p_temporada  );
            Participe participe = (Participe)qp.getSingleResult();

            if ( participe == null ) {
                throw new ExcepcionGeneral( -3, "Participe no encontrado" + p_equipo );
            }

            participe.setFavor  (participe.getFavor ()+p_favor  );
            participe.setContra (participe.getContra()+p_contra );

            participe.setGanados    ((short)(participe.getGanados   ()+p_ganados    ) );
            participe.setPerdidos   ((short)(participe.getPerdidos  ()+p_perdidos   ) );
            participe.setPuntos     (participe.getPuntos            ()+p_puntos       );

            p_em.persist(participe);
        } catch (Exception e) {
            log.error("Error: ", e);
        }
        /* finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        } */

    }

    public String wsTorneoRechazo( HttpServletRequest request, HttpServletResponse response ) {
        /* Consulta los partidos todavía no celebrados en torneos de usuario por un equipo
	   Respuesta:
	   Estará ordenada internamente al recuperar de la base de datos por calendario.f_fin de menor a mayor
           para que se jueguen primero los partidos que antes finalizará su fecha tope de celebración

	   error | cuantos |{torneo_id | rival | jornada | nombre |}  */

        int             culpable    = -1;
        int             rechazado   = -1;
        EntityManager   em          = null;
        String          respuesta   = "";
        Calendario      calendario  = null;

        try {
            em = emf.createEntityManager(); // check 07.08.2012
            culpable = Integer.parseInt(request.getParameter("culpable"));
            rechazado = Integer.parseInt(request.getParameter("rechazado"));

            Query q = em.createNamedQuery("Calendario.PartidoTemprano");
            q.setParameter("equipo_id1", culpable);
            q.setParameter("equipo_id2", rechazado);
            q.setParameter("fecha", new Date() );

log.debug("torneoRechazo "+culpable + " " + rechazado + " " + new Date());

            List<Calendario> lista = (List<Calendario>)q.getResultList();

            if ( lista.size()==0) {
                throw new ExcepcionGeneral( -6, "Enfrentamiento no encontrado" + culpable + " " + rechazado );
            } else {
                // Tomamos el primer enfrentamiento del calendario y asignamos su identificador al partido
                calendario = lista.get(0);

log.debug("calendarioEncontrado "+ calendario.getEquipo1().getId() + " " + calendario.getEquipo2().getId() );
                if ( calendario.getEquipo1().getId() == culpable ) {
                    calendario.setRechazo1((short)(calendario.getRechazo1()+1));
log.debug("aumentado rechazo 1 "+ calendario.getId() + " " + calendario.getRechazo1() );
                }

                if ( calendario.getEquipo2().getId() == culpable ) {
                    calendario.setRechazo2((short)(calendario.getRechazo2()+1));
log.debug("aumentado rechazo 2 "+ calendario.getId() + " " + calendario.getRechazo2() );
                }
                em.getTransaction().begin();
                em.persist(calendario);
                em.getTransaction().commit();
            }

            respuesta = "0|"+lista.size()+"|";

        } catch (Exception e) {
            try {
                if (em     != null && em.getTransaction().isActive() )
                    em.getTransaction().rollback();
            } catch (Exception e2) { }
            log.error("[torneoRechazo]: " , e);
            respuesta="-1|"+e.getMessage();
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
        return respuesta;

    }

    public String wsFinTorneosUsuario ( HttpServletRequest request, HttpServletResponse response  ) {
        EntityManager   em          =null;
        String          respuesta   =null;
        int             cuantos     =0;
        try {
            em = emf.createEntityManager(); // check 07.08.2012

            Date fecha = Util.FechaSiguiente(-15);

log.debug("---[Voy a buscar los torneos cuya fecha fFinPrevista superen 15 días para finalizarlos simulando] los partidos ");

            // Buscamos todas las temporadas cuya fecha de fin sea anterior a la de hoy (menos 15 dias)
            // y tenga estado 2 (Iniciada)
            Query q_temp = em.createNamedQuery("Temporada.findByEstadoMenorFecha");
            q_temp.setParameter("estado",   (short)2    );
            q_temp.setParameter("fecha",    fecha  );

            List<Temporada> l_temporada = (List<Temporada>)q_temp.getResultList();

            for ( int i=0;i<l_temporada.size();i++){
                this.finTemporada(l_temporada.get(i).getId());
                cuantos++;
            }
/*
Query q2_temp = em.createNamedQuery("Temporada.findByFFIN");
q2_temp.setParameter("fecha",    fecha  );
List<Temporada> l_temporada2 = (List<Temporada>)q2_temp.getResultList();
*/

log.debug("---[Voy a buscar los torneos que sus partidos ya hayan sido disputados");

            // Comprueba si una temporada activa tiene disputados ya todos sus partidos para finalizarla.
            // Para ello buscamos las temporadas que la fecha de fin haya llegado y
            // que no estén incluidas en las temporadas que alguno de sus partidos estén sin disputar
            Query q_nativa = em.createNativeQuery(
             "SELECT m.* FROM basket.temporada m where m.estado=2 and m.f_fin<:fecha and m.id not in"+
             "(select distinct(temporada_id) from basket.calendario where estado<10) ",Temporada.class);
                q_nativa.setParameter("fecha"  , new Date() );

            l_temporada = (List<Temporada>)q_nativa.getResultList();

            for ( int i=0;i<l_temporada.size();i++){
log.debug("-------------------------------");
log.debug("--- [Temporadas finalizadas]---"+l_temporada.get(i).getId());
log.debug("-------------------------------");
                this.finTemporada(l_temporada.get(i).getId());
                cuantos++;
            }

log.debug("--- [Voy a buscar los torneos que tras 30 dias no han comenzado");
            em.getTransaction().begin();
            // Vamos a borrar las temporadas que llevan más de un mes creadas y sin comenzar
            fecha = Util.FechaSiguiente(-30);
            Query q_borrar = em.createNamedQuery("Temporada.findNoArrancan");
            q_borrar.setParameter("fecha",    fecha  );
log.debug("--- Borrar Temporada Fecha: "+ fecha );

            List<Temporada> l_borrar = (List<Temporada>)q_borrar.getResultList();
            for ( int i=0;i<l_borrar.size();i++){
                Temporada temporada_borrar = l_borrar.get(i);

log.debug("--- Borrar Temporada "+ l_borrar.get(i).getId() );

                Query q_cal_borrar = em.createNamedQuery("Calendario.findByTemporadaId");
                q_cal_borrar.setParameter("temporada_id", temporada_borrar.getId()  );
                List<Calendario> l_cal_borrar = (List<Calendario>)q_cal_borrar.getResultList();
                for ( int a=0;a<l_cal_borrar.size();a++){
                    em.remove( l_cal_borrar.get(a));
log.debug("--- Borrar Calendario "+ l_cal_borrar.get(a).getId() );
                }

                Query q_jor_borrar = em.createNamedQuery("Jornada.findByTemporadaId");
                q_jor_borrar.setParameter("temporada_id", temporada_borrar.getId()  );
                List<Jornada> l_jor_borrar = (List<Jornada>)q_jor_borrar.getResultList();
                for ( int a=0;a<l_jor_borrar.size();a++){
                    em.remove( l_jor_borrar.get(a));
log.debug("--- Borrar Jornada "+ l_jor_borrar.get(a).getId() );
                }

                Query q_temporada = em.createNamedQuery("TemporadaTrofeo.findByTemporadaId");
                q_temporada.setParameter("temporada_id", temporada_borrar.getId()  );
                List<TemporadaTrofeo> listaqq = (List<TemporadaTrofeo>)q_temporada.getResultList();
                for ( int a=0;a<listaqq.size();a++){
                    em.remove( listaqq.get(a));
log.debug("--- Borrar TemporadaTrofeo "+ listaqq.get(a).getTemporada().getId() );
                }

                Query q_participe_borrar = em.createNamedQuery("Participe.findByTemporadaId");
                q_participe_borrar.setParameter("temporada_id", temporada_borrar.getId()  );
                List<Participe> lista_par = (List<Participe>)q_participe_borrar.getResultList();
                for ( int a=0;a<lista_par.size();a++){
                    em.remove( lista_par.get(a));
log.debug("--- Borrar Participe "+ lista_par.get(a).getTemporada().getId() );
                }

                em.remove(temporada_borrar);
            }

            respuesta="0|"+cuantos;

            em.getTransaction().commit();
        } catch (Exception e) {
            try {
                if (em     != null && em.getTransaction().isActive() )
                    em.getTransaction().rollback();
            } catch (Exception e2) { }
            log.error("[torneoPendientes]: " , e);
            respuesta="-1|"+e.getMessage();
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
        return respuesta;
        
    }


    private void finTemporada ( int p_temporada_id ) {
        // Realiza un final de temporada
        // Cerramos los partidos no jugados
        // Leemos los participes ordenados por puntos desc, favor-contra desc, y equipo_id asc
        // Leemos temporada_trofeo ordenado por posicion asc
        // Para cada temporada_trofeo creamos tupla en palmares
        // Finalmente ponemos la temporada como finalizada

        int             equipo_id   = -1;
        EntityManager   em          = null;
        Temporada temporada         = null;
        String          respuesta   = "";

        try {
            int posicion =0;

            em = emf.createEntityManager(); // check 07.08.2012
            em.getTransaction().begin();

            Query q_temp = em.createNamedQuery("Temporada.findById");
            q_temp.setParameter("id", p_temporada_id );
            temporada = (Temporada)q_temp.getSingleResult();
            if ( temporada != null ) {
log.debug ("Comprobando temporada"+p_temporada_id+ " estado "+ temporada.getEstado() );

                // finalizamos partidos no disputados
                Query q_no_disputado = em.createNamedQuery("Calendario.findByTemporadaIdNoDisputado");
                q_no_disputado.setParameter("temporada_id", p_temporada_id );
                List<Calendario> l_no_disputado = (List<Calendario>)q_no_disputado.getResultList();

                for ( int i=0;i<l_no_disputado.size();i++){
                    Calendario calendario = l_no_disputado.get(i);
                    calendario.setEstado    ((short)11);
                    calendario.setTanteo1   ((short)0);
                    calendario.setTanteo2   ((short)0);
                    em.persist(calendario);

                    // Actualizamos los perdidos de los partícipes
                    try {
                        Query q_participe1 = em.createNamedQuery ("Participe.findById");
                        q_participe1.setParameter("equipo_id", calendario.getEquipo1().getId() );
                        q_participe1.setParameter("temporada_id", p_temporada_id );
                        Participe participe1 = (Participe)q_participe1.getSingleResult();
                        participe1.setPerdidos((short)(participe1.getPerdidos()+1));
                        em.persist(participe1);
                    } catch (NoResultException nre) {
                        throw new ExcepcionGeneral( -20, "Calendario " + calendario.getId() 
                                +" sin participe " + calendario.getEquipo1().getId() );
                    }
                    try {
                        Query q_participe2 = em.createNamedQuery ("Participe.findById");
                        q_participe2.setParameter("equipo_id", calendario.getEquipo2().getId() );
                        q_participe2.setParameter("temporada_id", p_temporada_id );
                        Participe participe2 = (Participe)q_participe2.getSingleResult();
                        participe2.setPerdidos((short)(participe2.getPerdidos()+1));
                        em.persist(participe2);
                    } catch (NoResultException nre) {
                        throw new ExcepcionGeneral( -20, "Calendario " + calendario.getId()
                                +" sin participe " + calendario.getEquipo2().getId() );
                    }
                }

                Query ltt = em.createNamedQuery("TemporadaTrofeo.findByTemporadaId");
                ltt.setParameter("temporada_id", p_temporada_id );
                List<TemporadaTrofeo> l_temporada_trofeo = (List<TemporadaTrofeo>)ltt.getResultList();

                if ( l_temporada_trofeo.size()>0 ) {
                    // Entregamos trofeo a trofeo según la clasificación final
                    Query q = em.createNamedQuery("Participe.Clasificacion");
                    q.setParameter("temporada_id", p_temporada_id );
                    List<Participe> lista = (List<Participe>)q.getResultList();

                    for ( int i=0;i<l_temporada_trofeo.size();i++){
                        // 14/03/2012
                        // Si el participe al que vamos a entregar el premio
                        // está expulsado (estado 11)
                        // o no fue admitido a la temporada (estado 10),
                        // no le entregamos el premio y a partir de él
                        // tampoco a nadie más 
                        if ( lista.get(i).getEstado()==11 ||
                             lista.get(i).getEstado()==10 ) {
                            log.debug ("EXPULSADO NO PREMIAMOS " + lista.get(0).getParticipePK().getEquipo().getId()
                                    + " Temporada " + lista.get(0).getParticipePK().getTemporadaId());
                        } else {
                            Palmares    palmares = new Palmares();
                            PalmaresPK  palmares_pk = new PalmaresPK();
                                log.debug ("Entrega de premios Equipoid "+ lista.get(i).getParticipePK().getEquipo().getId()
                                        + " Temporada " + lista.get(0).getParticipePK().getTemporadaId() );
                            palmares_pk.setEquipoId( lista.get(i).getParticipePK().getEquipo().getId() );
                            palmares_pk.setTorneoId( l_temporada_trofeo.get(i).getTemporada().getTorneo().getId() );
                            palmares_pk.setZonaId( l_temporada_trofeo.get(i).getTemporada().getZonaId() );
                            
                            palmares_pk.setFecha(new Date());
                            palmares.setPalmaresPK(palmares_pk);

                            palmares.setTemporadaId(p_temporada_id);
                            palmares.setTrofeoId( l_temporada_trofeo.get(i).getTrofeo().getId() );
                            palmares.setPosicion((short)(i+1));


                            em.persist(palmares);
                        }
                    }
                }
log.debug ("Poner estado finalizado temporada"+p_temporada_id);
                temporada.setEstado((short)3);
                em.persist(temporada);

                em.getTransaction().commit();
            }

        } catch (Exception e) {
            try {
                if (em     != null && em.getTransaction().isActive() )
                    em.getTransaction().rollback();
            } catch (Exception e2) { }
            log.error("[torneoPendientes]: " , e);
            respuesta="-1|"+e.getMessage();
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
    }


    public String wsConsultarRankingT3( HttpServletRequest request, HttpServletResponse response ) {
        /* Consulta el ranking actual del concurso de triples

	   nick | puntos | tiempo */

        int             equipo_id   = -1;
        EntityManager   em          = null;
        String          respuesta   = "";

        try {
            em = emf.createEntityManager(); // check 07.08.2012
            Query q = em.createNamedQuery("RankingT3.findByPosicion");

            List<RankingT3> lista = (List<RankingT3>)q.getResultList();
            respuesta = "0|"+lista.size()+"|";

            // Tomamos el primer enfrentamiento y asignamos la jornada al partido
            for ( int i=0;i<lista.size();i++){
                RankingT3 elem = lista.get(i);
                respuesta   +=elem.getNombre()+"|"
                            + elem.getPuntos()+"|"
                            + elem.getTiempo()+"|";
            }

        } catch (Exception e) {
            try {
            } catch (Exception e2) { }
            log.error("[wsConsultarRankingT3]: " , e);
            respuesta="-1|"+e.getMessage();
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
        return respuesta;

    }

public String wsConsultarRankingT3Game( HttpServletRequest request, HttpServletResponse response ) {
        /* Consulta el ranking actual del concurso de triples

	   nick | puntos | tiempo */

        int             equipo_id   = -1;
        EntityManager   em          = null;
        String          respuesta   = "";

        try {
            em = emf.createEntityManager(); // check 07.08.2012
            Query q = em.createNamedQuery("RankingT3Game.findByPosicion");

            List<RankingT3Game> lista = (List<RankingT3Game>)q.getResultList();
            respuesta = "0|"+lista.size()+"|";

            // Tomamos el primer enfrentamiento y asignamos la jornada al partido
            for ( int i=0;i<lista.size();i++){
                RankingT3Game elem = lista.get(i);
                if ( elem.getEquipo() == null ) {
                    respuesta   +="---|---|---|0|0|" + elem.getPuntos() +"|";
                } else {
                    respuesta   +=elem.getEquipo().getUsuario().getNickMostrar()+"|"
                                + elem.getEquipo().getNombre()                  +"|"
                                + elem.getEquipo().getNick()                    +"|"
                                + elem.getJugador().getId()                     +"|"
                                + elem.getJugador().getMJugador().getId()       +"|"
                                + elem.getPuntos()                              +"|";
                }

            }

        } catch (Exception e) {
            try {
            } catch (Exception e2) { }
            log.error("[wsConsultarRankingT3Game]: " , e);
            respuesta="-1|"+e.getMessage();
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
        return respuesta;

    }


    public String wsGrabarRankingT3( HttpServletRequest request, HttpServletResponse response ) {
        /* Actualiza el ranking actual del concurso de triples
         *
         * el ranking se vacia cada noche en modo batch con:
         * update rankings.rankingT3 set puntos=posicion,tiempo=1000, nombre="nadie"
         *
	   nick | puntos | tiempo */

        int             equipo_id   = -1;
        EntityManager   em          = null;
        String          respuesta   = "";

        try {
            String  nombre = request.getParameter("nombre");
            Integer puntos = Integer.parseInt(request.getParameter("puntos"));
            Integer tiempo = Integer.parseInt(request.getParameter("tiempo"));

            if ( nombre == null || puntos == null || tiempo == null) {
                throw new ExcepcionGeneral( -1, "Parametros incorrectos " );
            }

            em = emf.createEntityManager(); // check 07.08.2012
            em.getTransaction().begin();

            Query q = em.createNamedQuery("RankingT3.findMenor");
            q.setParameter("puntos", puntos );
            q.setParameter("tiempo", tiempo );


            List<RankingT3> lista = (List<RankingT3>)q.getResultList();

            // Si no hay menores no grabo nada

            if ( lista.size()> 0 ) {
log.debug("[wsGrabarRankingT3] elementos: " + lista.size() +
    lista.get(0).getNombre() + " p:" + lista.get(0).getPuntos() + " t:" + lista.get(0).getTiempo());

                /* Hacemos Hueco desplazando una posición hacia abajo los valores del ranking */
                for ( int i=0;i<lista.size()-1;i++){

log.debug("[wsGrabarRankingT3] anterior: " + (lista.size()-i-2) + " actual" + (lista.size()-i-1) );

                    RankingT3 anterior = lista.get(lista.size()-i-2);
                    RankingT3 actual   = lista.get(lista.size()-i-1);

                    actual.setNombre(anterior.getNombre());
                    actual.setPuntos(anterior.getPuntos());
                    actual.setTiempo(anterior.getTiempo());

                    em.persist(actual);
                }
                // Apuntamos el nuevo record
                // 14 de febrero de 2012 limitamos la longitud del nombre para que no de error al grabar
                if ( nombre.length()>20 )
                    lista.get(0).setNombre(  nombre.substring(0,20)   );
                else
                    lista.get(0).setNombre(  nombre  );
                lista.get(0).setPuntos(puntos);
                lista.get(0).setTiempo(tiempo);

                em.persist(lista.get(0));
            } 
            respuesta = "0|";
            em.getTransaction().commit();
        } catch (Exception e) {
            try {
            } catch (Exception e2) { }
            log.error("[wsGrabarRankingT3]: " , e);
            respuesta="-1|"+e.getMessage();
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
        return respuesta;

    }

    public String wsGrabarRankingT3Game( HttpServletRequest request, HttpServletResponse response ) {
        // Actualiza el ranking actual del concurso de triples dentro del juego
        //
        // Para que funcione el ranking tiene que haber 10 huecos numerados por posición
        //
        // el ranking se vacia cada noche en modo batch con:
        // update rankings.rankingT3 set puntos=posicion,jugador_id=null
        //
	//   
        //
        //   retorno:
        //     -1 - Parámetros incorrectos
        //     -2 - Sesión Incorrecta
        //     -3 - No existe el jugador
        EntityManager   em          = null;
        String          respuesta   = "";
        String          subida      = "";


        try {
            LoginAction la          = new LoginAction();
            HttpSession miSesion    = request.getSession(true);
            String      sesion_id   = miSesion.getId();

            Integer jugador_id  = Integer.parseInt(request.getParameter("jugador_id"));
            Integer equipo_id   = Integer.parseInt(request.getParameter("equipo_id"));
            Integer puntos      = Integer.parseInt(request.getParameter("puntos"));
            String  hash        =                  request.getParameter("hash");

            em = emf.createEntityManager(); // check 07.08.2012

            if ( jugador_id == null || puntos == null || equipo_id == null || hash == null) {
                throw new ExcepcionGeneral( -1, "Parametros incorrectos " );
            }

            String cadena = Integer.toString(puntos*equipo_id*jugador_id*49632);
            MessageDigest md = MessageDigest.getInstance("SHA1");
            md.reset();
            md.update(cadena.getBytes(Charset.forName("UTF8")));
            byte[] resultByte = md.digest();
            String result = new String(Hex.encodeHex(resultByte));

log.debug("[wsGrabarRankingT3] calculado " + result + " enviado " + hash );
            if ( result.compareTo(hash) != 0 ) {
                throw new ExcepcionGeneral( -1, "Parametros incorrectos " );
            }
            
            int equipo_id_sesion = la.comprobarSesionEquipo(sesion_id, equipo_id, em);
            if ( equipo_id_sesion < 1 ) {
                throw new ExcepcionGeneral( -2, "Sesion Incorrecta " );
            }

            Query qr = em.createNamedQuery("RankingT3Game.findMenor");
            qr.setParameter("puntos", puntos );

            List<RankingT3Game> lr = (List<RankingT3Game>)qr.getResultList();

            // Si no hay menores no grabo nada
            if ( lr.size()> 0 ) {
                em.getTransaction().begin();
                
                boolean dar_experiencia = false;
                int     exp_ganada      = 0;
                if ( lr.get(0).getEquipo()!= null )
                    log.debug("[wsGrabarRankingT3Game] elementos: " + lr.size() + " " +
                        lr.get(0).getEquipo().getNombre() + " p:" + lr.get(0).getPuntos() );

                // Voy a buscar el jugador
                Query qj = em.createNamedQuery("Jugador.findById");
                qj.setParameter("id", jugador_id );

                List<Jugador> lj = (List<Jugador>)qj.getResultList();
                if ( lj.isEmpty() ) {
                    throw new ExcepcionGeneral( -3, "No existe el jugador" );
                }
                Jugador jugador_anotar = lj.get(0);

                // Hacemos Hueco desplazando una posición hacia abajo los valores del ranking
                for ( int i=0;i<lr.size()-1;i++){
log.debug("[wsGrabarRankingT3] anterior: " + (lr.size()-i-2) + " actual" + (lr.size()-i-1) );

                    RankingT3Game anterior = lr.get(lr.size()-i-2);
                    RankingT3Game actual   = lr.get(lr.size()-i-1);

                    actual.setPuntos    (anterior.getPuntos());
                    actual.setEquipo    (anterior.getEquipo());
                    actual.setJugador   (anterior.getJugador());
                    actual.setMJugador  (anterior.getMJugador());

                    em.persist(actual);
                }

                exp_ganada = -10 * ( lr.get(0).getPosicion() -11 ) ;

log.debug("[Posicion] " + lr.get(0).getPosicion() + " experiencia" + exp_ganada );

                lr.get(0).setPuntos  (puntos);
                lr.get(0).setEquipo  (jugador_anotar.getEquipo());
                lr.get(0).setJugador (jugador_anotar);
                lr.get(0).setMJugador(jugador_anotar.getMJugador());

                em.persist(lr.get(0));


                dar_experiencia = darExperienciaT3 ( em, jugador_id);


                if ( dar_experiencia ) {
                    MultiJugador multi  = new MultiJugador();
                    multi.jugador       = jugador_anotar;

                    DatosEquipo de = new DatosEquipo();
                    de.aumentaExpJugador ( em, multi, exp_ganada);

                    if ( multi.subida_nivel ) {
                        subida ="|"+multi.carac_subida+"|"+ multi.puntos_subida +"|";
                    }
                } else {
                    exp_ganada = 0;
                }

                em.getTransaction().commit();

                respuesta = "0|"+Integer.toString(exp_ganada)+subida;
            } else {
                respuesta = "0|";
            }

        } catch (ExcepcionGeneral ex) {
            if (em != null && em.getTransaction().isActive() )
                em.getTransaction().rollback();

            log.error("[wsGrabarRankingT3Game]: " , ex);
            respuesta = ex.getCodigo()+"|"+ex.getDescripion();            
        } catch (Exception e) {
            if (em != null && em.getTransaction().isActive() )
                em.getTransaction().rollback();

            try {
            } catch (Exception e2) { }
            log.error("[wsGrabarRankingT3Game]: " , e);
            respuesta="-1|"+e.getMessage();
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
        return respuesta;

    }
    
    private boolean darExperienciaT3 ( EntityManager em, int jugador_id ) {
        // Si es menor que cinco las veces que ha ganado hoy Experiencia
        // el jugador, volvemos a darle experiencia
        // Guardamos las veces que hemos entregado experiencia

        boolean     dar_experiencia = true;
        Query       qexp            = em.createNamedQuery("T3Experiencia.findById");
        qexp.setParameter("jugador_id", jugador_id );

        List<T3Experiencia> lexp = (List<T3Experiencia>)qexp.getResultList();
        if ( !lexp.isEmpty() ) {
            T3Experiencia t3_experiencia = lexp.get(0) ;
            if ( t3_experiencia.getVeces() > 4 ) {
                dar_experiencia= false;
                log.debug("[t3 demasiado] " + t3_experiencia.getVeces() );
            } else {
                // Aumentamos las veces que ha recibido hoy experiencia el jugador
                t3_experiencia.setVeces(t3_experiencia.getVeces()+1);
                em.persist(t3_experiencia);
            }

        } else {
            T3Experiencia t3_experiencia = new T3Experiencia();
            t3_experiencia.setJugadorId(jugador_id);
            t3_experiencia.setVeces(1);
            em.persist(t3_experiencia);
        }

        return dar_experiencia;
    }

    // Guarda en la tabla de Ultimos Partido los contendientes
    int GrabarUltimosPartidos ( EntityManager em, Equipo p_equipo, Equipo p_rival ) {

        UltimosPartidos ultimos = null;

        Query       qult = em.createNamedQuery("UltimosPartidos.findByEquipoId");
        qult.setParameter("equipo_id", p_equipo.getId() );
        List<UltimosPartidos> lult = (List<UltimosPartidos>)qult.getResultList();
        if ( !lult.isEmpty() ) {
            ultimos = lult.get(0);
            if ( ultimos.getEq1() != p_rival.getId() &&
                 ultimos.getEq2() != p_rival.getId() &&
                 ultimos.getEq3() != p_rival.getId() &&
                 ultimos.getEq4() != p_rival.getId() &&
                 ultimos.getEq5() != p_rival.getId() &&
                 ultimos.getEq6() != p_rival.getId()
                ) {
                    
log.debug("+++++ GUARDANDO ULTIMO RIVAL " + ultimos.getId() + " Equipo " + p_rival.getId() );
                    
                    ultimos.setEq6(ultimos.getEq5());
                    ultimos.setEq5(ultimos.getEq4());
                    ultimos.setEq4(ultimos.getEq3());
                    ultimos.setEq3(ultimos.getEq2());
                    ultimos.setEq2(ultimos.getEq1());
                    ultimos.setEq1(p_rival.getId());
                    em.persist(ultimos);
            }
        } else {
            ultimos = new UltimosPartidos();
            ultimos.setId ( p_equipo.getId());
            ultimos.setEq1( p_rival.getId());
            em.persist(ultimos);
        }
        return 0;
    }

    boolean EnfrentadosUltimosPartidos ( EntityManager em, Equipo p_equipo, Equipo p_rival ) {

/*        
        UltimosPartidos ultimos = null;

        Query       qult = em.createNamedQuery("UltimosPartidos.findByEquipoId");
        qult.setParameter("equipo_id", p_equipo.getId() );
        List<UltimosPartidos> lult = (List<UltimosPartidos>)qult.getResultList();
        if ( !lult.isEmpty() ) {
            ultimos = lult.get(0);
            if ( ultimos.getEq1() == p_rival.getId() ||
                 ultimos.getEq2() == p_rival.getId() 

//                 ultimos.getEq3() == p_rival.getId() ||
//                 ultimos.getEq4() == p_rival.getId() ||
//                 ultimos.getEq5() == p_rival.getId() ||
//                 ultimos.getEq6() == p_rival.getId()

                ) {
                    return true;
            }
        }
        */
        
        return false;
    }

    
    
    public boolean HoraRankingAbierto() {
        Calendar ahora = Calendar.getInstance();
            
        if (ahora.get( Calendar.HOUR_OF_DAY)<conf.BuscarValorConfiguracionInteger("hora_ranking_ini") ||
            ahora.get( Calendar.HOUR_OF_DAY)>conf.BuscarValorConfiguracionInteger("hora_ranking_fin") ) {
log.debug("RANKING ABIERTO HORA "+ahora.get(Calendar.HOUR_OF_DAY)+ " hour " + ahora.get(Calendar.HOUR) + " AM_PM " + ahora.get(Calendar.AM_PM));                                
            return true;
        } else {
log.error("RANKING CERRADO HORA "+ahora.get(Calendar.HOUR_OF_DAY)+ " hour " + ahora.get(Calendar.HOUR) + " AM_PM " + ahora.get(Calendar.AM_PM));                                
            return false;
        }
    }

    
    // v2.13 Nueva función para centralizar Ranking Promo Pool cerrado
    boolean RankingPromoPoolAbierto () {
        if  (Calendar.getInstance().get(Calendar.DAY_OF_MONTH)!=1 &&
             Calendar.getInstance().get(Calendar.DAY_OF_MONTH)!=16 ) {
            return true;
        }
        // Si es día 1 o 16 solo dependerá de la Hora
        return HoraRankingAbierto();
    }
    
    // v2.13
    // Si es un partido de un PromoPool contra un Pro
    // solo gana o pierde 5 ASP y NO se incremente el contador de
    // partidos de elo
    int calcularEloContraPro ( EntityManager em, Equipo p_equipo, 
                               Equipo p_rival, Partido p_partido  )
        throws ExcepcionGeneral {

        Elo elo = null;

        if (  RankingPromoPoolAbierto() ) 
        {
            if ( p_equipo.getNivel()>=15 && p_rival.getNivel()<15 ) {
                Query       q1 = em.createNamedQuery("Elo.findByEquipoId");
                q1.setParameter("equipo_id", p_equipo.getId() );
                elo = (Elo)q1.getSingleResult();
                if ( elo == null ) {
                    throw new ExcepcionGeneral( -3, "Elo no encontrado" + p_equipo.getId()  );
                }
                
                if ( p_partido.getPuntos1() > p_partido.getPuntos2() ) {
                    elo.setElo(elo.getElo()+5);
                } else {
                    elo.setElo(elo.getElo()-5);
                }
                em.persist(elo);
            }

            if ( p_equipo.getNivel()<15 && p_rival.getNivel()>=15 ) {
                Query       q1 = em.createNamedQuery("Elo.findByEquipoId");
                q1.setParameter("equipo_id", p_rival.getId() );
                elo = (Elo)q1.getSingleResult();
                if ( elo == null ) {
                    throw new ExcepcionGeneral( -3, "Elo no encontrado" + p_rival.getId()  );
                }
                
                if ( p_partido.getPuntos2() > p_partido.getPuntos1() ) {
                    elo.setElo(elo.getElo()+5);
                } else {
                    elo.setElo(elo.getElo()-5);
                }
                em.persist(elo);
            }
        }
        return 0;
    }

    
    int calcularElo ( EntityManager em, Equipo p_equipo, Equipo p_rival, 
                      Partido p_partido, int p_abandono, int p_cuarto_juego
                    )
        throws ExcepcionGeneral {

        boolean p_ranking_abierto = HoraRankingAbierto();
        
        double cte1 = 100;
        double cte2 = 800;


        Elo elo1 = null;
        Elo elo2 = null;

        Query       q1 = em.createNamedQuery("Elo.findByEquipoId");
        q1.setParameter("equipo_id", p_equipo.getId() );
        elo1 = (Elo)q1.getSingleResult();
        if ( elo1 == null ) {
            throw new ExcepcionGeneral( -3, "Elo1 no encontrado" + p_equipo.getId()  );
        }
       
        Query       q2 = em.createNamedQuery("Elo.findByEquipoId");
        q2.setParameter("equipo_id", p_rival.getId() );
        elo2 = (Elo)q2.getSingleResult();
        if ( elo2 == null) {
            throw new ExcepcionGeneral( -3, "Elo2 no encontrado" + p_rival.getId()  );
        }

        int puntos1=0;
        int puntos2=0;
        

        elo1.setUltimosJugados(elo1.getUltimosJugados()+1);
        elo2.setUltimosJugados(elo2.getUltimosJugados()+1);  
        
        if ( p_partido.getPuntos1() > p_partido.getPuntos2() ) {
            puntos1=1;
            elo1.setGanadosElo(elo1.getGanadosElo()+1);
            elo2.setPerdidosElo(elo2.getPerdidosElo()+1);
         } else {
            puntos2=1;
            elo2.setGanadosElo(elo2.getGanadosElo()+1);
            elo1.setPerdidosElo(elo1.getPerdidosElo()+1);            
        }

        double nuevo_elo1 = elo1.getElo() + (cte1 * ( puntos1-1 / ( Math.pow(10, (( elo2.getElo()-elo1.getElo() ) /cte2)) +1))) ;
        double nuevo_elo2 = elo2.getElo() + (cte1 * ( puntos2-1 / ( Math.pow(10, (( elo1.getElo()-elo2.getElo() ) /cte2)) +1))) ;

        log.debug(" Antiguo " + p_equipo.getId() + " Elo " + elo1.getElo() + " diferencia " + (nuevo_elo1 - elo1.getElo()) );
        log.debug(" Antiguo " + p_rival.getId()  + " Elo " + elo2.getElo() + " diferencia " + (nuevo_elo2 - elo2.getElo()) );
        
        elo1.setElo((float)nuevo_elo1);
        elo2.setElo((float)nuevo_elo2);

        if ( p_partido.getTipo()== 6 ) {
            if ( elo1.getZona() != elo2.getZona() )
                throw new ExcepcionGeneral( -3, "ZONAS INCOMPATIBLES" + elo1.getZona() + " - " + elo2.getZona()  );
            if ( elo1.getDivision() != elo2.getDivision() )
                throw new ExcepcionGeneral( -3, "DIVISIONES INCOMPATIBLES" + elo1.getDivision() + " - " + elo2.getDivision()  );

            // Si abandonas un partido de división pierdes el 5% de elo
            if ( p_equipo.getId()==p_abandono )  {
log.error("-->Abandonador partido division "+p_equipo.getId()+ " elo antes: " + elo1.getElo() );                                    
                    elo1.setElo( elo1.getElo()-(elo1.getElo()*(float)0.05) );
log.error("-->Abandonador partido division "+p_equipo.getId()+ " elo despues: " + elo1.getElo() );                                    
            }
            if ( p_rival.getId()==p_abandono )  {
log.error("-->Abandonador partido division "+p_rival.getId()+ " elo antes: " + elo2.getElo() );                                                    
                    elo2.setElo( elo2.getElo()-(elo2.getElo()*(float)0.05) );
log.error("-->Abandonador partido division "+p_rival.getId()+ " elo despues: " + elo2.getElo() );                                                                        
            }
            
            
log.debug("dia del mes Ranking Abierto "+p_ranking_abierto + " dia del mes " + Calendar.getInstance().get(Calendar.DAY_OF_MONTH) );
            if ( RankingPromoPoolAbierto()  
/*                    
                  p_ranking_abierto ||
                  (Calendar.getInstance().get(Calendar.DAY_OF_MONTH)!=1 &&
                   Calendar.getInstance().get(Calendar.DAY_OF_MONTH)!=16  ) 
*/
                ) {

                int puntos_acumular1= puntosAcumularDivision ( p_equipo, (p_equipo.getId()==p_abandono),
                            (p_partido.getPuntos1()>p_partido.getPuntos2()),
                             p_cuarto_juego,p_partido.getMinutos() );
                int puntos_acumular2= puntosAcumularDivision ( p_rival, (p_rival.getId()==p_abandono),
                            (p_partido.getPuntos2()>p_partido.getPuntos1()),
                             p_cuarto_juego,p_partido.getMinutos() );

                if ( p_partido.getPuntos1() > p_partido.getPuntos2() ) {
                    elo1.setGanados(elo1.getGanados()+1);
                    elo2.setPerdidos(elo2.getPerdidos()+1);
                 } else {
                    elo2.setGanados(elo2.getGanados()+1);
                    elo1.setPerdidos(elo1.getPerdidos()+1);
                }

                elo1.setDivisionPuntos(elo1.getDivisionPuntos()+puntos_acumular1);
                elo2.setDivisionPuntos(elo2.getDivisionPuntos()+puntos_acumular2);

                GrabarCruceDivision ( em, p_equipo, p_rival, p_partido,
                                      elo1.getZona() , elo1.getDivision(),
                                      puntos_acumular1,puntos_acumular2);
            } else {
                log.error("Ranking Division cerrado partido_id: "+ p_partido.getId()   );
                // 27-05-2013 Para que no queden reflejados como partidos de división, 
                // sino como partidos de ELO
                p_partido.setTipo((short)5);
            }
        }

        em.persist(elo1);
        em.persist(elo2);

        return 0;
    }

    // Guarda el cruce de dos equipos en una división de ELO 
    int GrabarCruceDivision ( EntityManager em, Equipo p_equipo, Equipo p_rival, 
                        Partido p_partido, int p_zona, int p_division,
                        int p_puntos_ganados_1, int p_puntos_ganados_2) {


        CruceDivision cruce = new CruceDivision();
        CruceDivisionPK crucePK = new CruceDivisionPK();

        crucePK.setZona     ( p_zona );
        crucePK.setDivision ( p_division );
        crucePK.setEquipoId1( p_partido.getEquipo1Id());
        crucePK.setEquipoId2( p_partido.getEquipo2Id());

        cruce.setId       ( crucePK );
        cruce.setPartidoId( p_partido.getId());
        cruce.setPuntos1  ( p_puntos_ganados_1 );
        cruce.setPuntos2  ( p_puntos_ganados_2 );
        cruce.setAnotado1 ( p_partido.getPuntos1());
        cruce.setAnotado2 ( p_partido.getPuntos2());

        em.persist(cruce);

        return 0;
    }

    public int puntosAcumular ( Equipo p_equipo, boolean p_abandonador,
            boolean p_ganador, int p_ultimo_cuarto_acabado, int p_tiempo_por_cuarto ) {
        // Reglas Ranking acumlado   ganador perdedor
        // Partido Amistoso             0       0
        // Partido Regular              3       1
        // Partido Express              1       0
        // Regular 2 cuartos jugados    1       0
        int puntos=0;

        if ( p_abandonador ) {
            log.debug("::guardaAcumulado "+ p_equipo.getId() +" abandonador 0 puntos"    );
            puntos=-1;
        } else {
            switch ( p_tiempo_por_cuarto) {
                case 1:
                    log.debug("::guardaAcumulado "+ p_equipo.getId() +" express 1 punto"  );
                    // express
                    if (  p_ganador && p_ultimo_cuarto_acabado>2 )
                        puntos = 1;
                    break;
                case 2:
                    // regular
                    if ( p_ganador) {
                        if ( p_ultimo_cuarto_acabado>2 ) {
                            log.debug("::guardaAcumulado "+ p_equipo.getId() +" ganador +2 cuartos 3 puntos"  );
                            puntos = 3;
                        }  else {
                            log.debug("::guardaAcumulado "+ p_equipo.getId() +" ganador <2 cuartos 1 puntos"    );
                            puntos = 1;
                        }
                    } else {
                        if ( p_ultimo_cuarto_acabado>2 ) {
                            log.debug("::guardaAcumulado "+ p_equipo.getId() +" perdedor +2 cuartos 1 puntos"    );
                            puntos = 1;
                        } else {
                            log.debug("::guardaAcumulado "+ p_equipo.getId() +" perdedor <2 cuartos 0 puntos"    );
                        }
                    }
                    break;
            }
        }
        return puntos;
    }

    public int puntosAcumularDivision ( Equipo p_equipo, boolean p_abandonador,
            boolean p_ganador, int p_ultimo_cuarto_acabado, int p_tiempo_por_cuarto ) {
        // Reglas Ranking acumlado   ganador perdedor
        // Partido Amistoso             0       0
        // Partido Regular              3       1
        // Partido Express              1       0
        // Regular 2 cuartos jugados    1       0
        int puntos=0;

        if ( p_abandonador ) {
            log.debug("::guardaAcumulado "+ p_equipo.getId() +" abandonador division -1 puntos"    );
            puntos=-1;
        } else {
            if ( p_ganador) {
                log.debug("::guardaAcumulado "+ p_equipo.getId() +" ganador divison 3 puntos"  );
                puntos = 3;
            } else {
                log.debug("::guardaAcumulado "+ p_equipo.getId() +" perdedor divison 1 puntos"  );
                puntos = 1;                
            }
        }
        return puntos;
    }
    
    
    public int CrearElo ( EntityManager p_em, Equipo p_equipo ) {

        Elo elo = new Elo ();
        elo.setEquipoId(p_equipo.getId());
        elo.setDivision(0);
        elo.setDivisionPuntos(0);
        elo.setElo(2400);
        elo.setGanados(0);
        elo.setPerdidos(0);
        // 12/06/2013 Bug se guardaba siempre la zona 0 a los equipos
        elo.setZona( p_equipo.getZonaId() );
        p_em.persist(elo);

        return 0;
    }


}
